// tofwov.cxx -- TOF Wall overlap analysis

#include <iostream>
#include <TFile.h>
#include <TTree.h>
#include <TH2F.h>
#include <TCanvas.h>
#include <TClonesArray.h>

// #include "ETFPlaHit.h"
// #include "ETFTrack.h"

using std::cout;
using std::endl;
using std::flush;

#define DEC2023

#ifdef DEC2023
//-- for dec_2023 exp --//
static const double tof2_ofst = 188.9; // ns
static const int ID[2] = {10, 11};
#else
//-- for jul_2018 exp --//
static const double tof2_ofst = 90.7; // ns
static const int ID[2] = {23, 24};
#endif

void tofwov(){
  // TFile *f = new TFile("tofw.root", "UPDATE");
  TFile *f = new TFile(getenv("TMP1"), "UPDATE");
  TTree *etf = (TTree *)f->Get("etf");
  TCutG *kr78 = (TCutG *)f->Get("kr78");
  if(kr78){ // set entry list
    etf->Draw(">>el", "kr78", "entrylist");
    TEntryList *el = (TEntryList *)f->Get("el");
    etf->SetEntryList(el);
  } // end if
  const int n = etf->GetEntries("");
  cout << "Totally " << n << " events" << endl;

  char title[128]{};
  sprintf(title, "tof2 v.s. hit pos on TOF Wall - stripId={%d, %d}", ID[0], ID[1]);
  TH2F *h2xt1 = new TH2F("h2xt1", title, 1000, 210., 420., 1000, 55., 100.); // 1000, 210., 420.
  TH2F *h2xt1_2 = new TH2F("h2xt1_2", title, 1000, 210., 420., 1000, 55., 100.);
  TH2F *h2xt2 = new TH2F("h2xt2", title, 1000, 210., 420., 1000, 55., 100.);
  sprintf(title, "tof2 (stripId %d) v.s. tof2 (stripId %d)", ID[1], ID[0]);
  h2xt1->SetMarkerColor(1);
  h2xt1_2->SetMarkerColor(2);
  h2xt2->SetMarkerColor(3);
  h2xt1->GetXaxis()->SetTitle("hit X on TOF Wall [mm]");
  h2xt1->GetYaxis()->SetTitle("tof2 [ns]");

  TH2F *h2tt = new TH2F("h2xtt", title, 1000, 55., 80., 1000, 55., 80.);
  sprintf(title, "tof2 [ns] - strip Id %d", ID[0]);
  h2tt->GetXaxis()->SetTitle(title);
  sprintf(title, "tof2 [ns] - strip Id %d", ID[1]);
  h2tt->GetYaxis()->SetTitle(title);
  sprintf(title, "tof2 strip Id %d [ns] - hit pos on TOF Wall", ID[1]);
  TH2F *h2tt_p = new TH2F("h2tt_p", title, 1000, -100., 50., 1000, 55., 80.);
  h2tt_p->GetXaxis()->SetTitle("hit X on TOF Wall [mm]");
  h2tt_p->GetYaxis()->SetTitle("tof2 [ns]");
  sprintf(title, "tof2 strip Id %d v.s. TOT", ID[1]);
  TH2F *h2tt_tot = new TH2F("h2tt_tot", title, 1000, 0., 500., 1000, 55., 80.);
  h2tt_tot->GetXaxis()->SetTitle("TOT [ns]");
  h2tt_tot->GetYaxis()->SetTitle("tof2 [ns]");
  sprintf(title, "tof2 strip Id %d v.s. TOT", ID[0]);
  TH2F *h2tt_tot_2 = new TH2F("h2tt_tot_2", title, 1000, 55., 80., 1000, 0., 500.);
  h2tt_tot_2->GetXaxis()->SetTitle("tof2 [ns]");
  h2tt_tot_2->GetYaxis()->SetTitle("TOT [ns]");

  // TCut cut = "1 "
  //   "(tofwB[1].stripId()-tofwB[0].stripId()==1)&&Length$(tofwB)>=2"
  // ;
  // etf->Draw(">>el", cut, "entrylist");
  // TEntryList *el = (TEntryList *)f->Get("el");
  // etf->SetEntryList(el);
  TClonesArray *cl = new TClonesArray("ETFPlaHit");
  TClonesArray *cltrk = new TClonesArray("ETFTrack"); // postMagTrackerX
  TClonesArray *clt1 = new TClonesArray("ETFPlaHit");
  etf->SetBranchAddress("tofwB", &cl);
  etf->SetBranchAddress("postMagTrackerX", &cltrk);
  etf->SetBranchAddress("tstop", &clt1);
  double ettof2;
  etf->SetBranchAddress("et.tof2", &ettof2);
  for(int i = 0; i < n; i++){
    etf->GetEntry(i);
    // cout << "tof2: " << ettof2 << endl; getchar(); // DEBUG
    if(clt1->GetEntriesFast() != 1) continue;
    ETFPlaHit *ht1 = dynamic_cast<ETFPlaHit *>(clt1->At(0));
    if(ht1->fired() != 4) continue;
    const double t1 = ht1->GetTime() - tof2_ofst;
    if(cltrk->GetEntriesFast() != 1) continue;
    ETFTrack *trk = dynamic_cast<ETFTrack *>(cltrk->At(0));
    const int idtrk = trk->GetFiredStripId();
    ETFPlaHit *ho[2]{}; // adjacent strips with fired()==4
    ETFPlaHit *h0 = nullptr; // strip id of the last strip
    for(TObject *b : *cl){
      ETFPlaHit *h = dynamic_cast<ETFPlaHit *>(b);
      if(h && h->fired() == 4){
        if(!h0) h0 = h;
        else{ // test the 2nd strip
          const int id0 = h0->stripId(), id = h->stripId();
          if(abs(id - id0) == 1 && (id == idtrk || id0 == idtrk)){ // BINGO
            ho[0] = h0; ho[1] = h;
            break;
          }
          else{ // use the 2nd strip as the 1st one again
            h0 = h;
            ho[0] = ho[1] = nullptr; // may be unnecessary
          }
        } // end else
      } // end if
    } // end for over hits
    if(!h0) continue; // no eligible strips
    // the adjacent strips //
    const double hx = trk->GetHitPos("tofwB");
    if(ho[0] && ho[1] && ho[0]->stripId() == ID[0] && ho[1]->stripId() == ID[1]){
      const double tof2[2] = {ho[0]->GetTime() - t1, ho[1]->GetTime() - t1};
      h2xt1->Fill(hx, tof2[0] + 20.);
      h2xt1_2->Fill(hx, tof2[1]);
      h2xt2->Fill(hx, ettof2 + 5.);
      h2tt->Fill(tof2[0], tof2[1]);
      if(tof2[1] > 59. && tof2[1] < 62.) h2tt_p->Fill(hx, tof2[0]);
      h2tt_tot->Fill(ho[1]->tot(), tof2[1]);
      h2tt_tot_2->Fill(tof2[0], ho[0]->tot());
    } // end if
    else{
      // single strips //
      const int id0 = h0->stripId();
      if(id0 == idtrk && (ID[0] == id0 || ID[1] == id0)){
        const double tof2 = h0->GetTime() - t1;
        if(ID[0] == id0) h2xt1->Fill(hx, tof2 + 20.);
        if(ID[1] == id0) h2xt1_2->Fill(hx, tof2);
        h2xt2->Fill(hx, ettof2 + 5.);
      }
    } // end else
    cout << "Processing event " << i << '\r' << flush;
  } // end for over i

  TCanvas *c = new TCanvas("c", "c", 1400, 1200);
  c->Divide(2,2);
  c->cd(3)->SetGrid();
  h2xt1->Draw("box");
  h2xt1_2->Draw("samebox");
  h2xt2->Draw("colsamebox");
  c->cd(2)->SetGrid();
  h2tt->Draw("colbox");
  c->cd(1)->SetGrid();
  h2tt_tot->Draw("colbox");
  // h2tt_p->Draw("colbox");
  c->cd(4)->SetGrid();
  // h2tt_tot->Draw("colbox");
  h2tt_tot_2->Draw("colbox");

  h2xt1->Write("", TObject::kOverwrite);
  h2xt1_2->Write("", TObject::kOverwrite);
  h2xt2->Write("", TObject::kOverwrite);
  h2tt->Write("", TObject::kOverwrite);
  h2tt_p->Write("", TObject::kOverwrite);
  h2tt_tot->Write("", TObject::kOverwrite);
  h2tt_tot_2->Write("", TObject::kOverwrite);
  c->Write("", TObject::kOverwrite);
  c->Print("tofwov.pdf");
} // end main function
